package cn1socket;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.EOFException;
import java.net.Socket;


public final class NativeSocketImpl implements cn1socket.NativeSocket {
	private Socket socket;
	private InputStream in;
	private OutputStream out;
	private String ex = null;
	private String msg;

	@Override public boolean isSupported() {
		return true;
	}

	private void handle(IOException e) {
//		e.printStackTrace();
		ex = e instanceof EOFException ? "EOFException" : "IOException";
		msg = e.getMessage();
	}

	@Override public String getException() {
		String s = ex;
		ex = null;
		return s;
	}

	@Override public String getExceptionMessage() {
		return msg;
	}

	@Override public void connect(String host,int port) {
		try {
			socket = new Socket(host,port);
			in = socket.getInputStream();
			out = socket.getOutputStream();
		} catch(IOException e) {
			handle(e);
		}
	}

	@Override public void close() {
		try {
			socket.close();
		} catch(IOException e) {
			handle(e);
		}
	}


	// InputStream

	@Override public int available() {
		try {
			return in.available();
		} catch(IOException e) {
			handle(e);
			return -1;
		}
	}

	@Override public int read() {
		try {
			return in.read();
		} catch(IOException e) {
			handle(e);
			return -1;
		}
	}

	@Override public byte[] read(int length) {
		try {
			byte[] buf = new byte[length];
			int n = in.read(buf);
			if( n == -1 )
				return null;
			if( n == length )
				return buf;
			byte[] rtn = new byte[n];
			System.arraycopy(buf, 0, rtn, 0, n);
			return rtn;
		} catch(IOException e) {
			handle(e);
			return null;
		}
	}


	// OutputStream

	@Override public void flush() {
		try {
			out.flush();
		} catch(IOException e) {
			handle(e);
		}
	}

	@Override public void write(int b) {
		try {
			out.write(b);
		} catch(IOException e) {
			handle(e);
		}
	}

	@Override public void writeBuffer(byte[] b) {
		try {
			out.write(b);
		} catch(IOException e) {
			handle(e);
		}
	}

	@Override public void writeBuffer(byte[] b, int off, int len) {
		try {
			out.write(b,off,len);
		} catch(IOException e) {
			handle(e);
		}
	}

}
